package com.demo.crm.springboot3security.service;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@EnableScheduling
@RequiredArgsConstructor
public class CacheMonitorService {

    private final CacheManager cacheManager;
    private final MeterRegistry meterRegistry;

    private static final List<String> CACHE_NAMES = Arrays.asList(
            "formData", "formQuery", "formAggregate", "formRelated"
    );

    /**
     * 每分钟记录缓存统计信息
     */
    @Scheduled(fixedRate = 60_000)
    public void recordCacheMetrics() {
        CACHE_NAMES.forEach(this::updateCacheMetrics);
    }

    /**
     * 获取缓存统计信息
     */
    public CacheStats getCacheStats(String cacheName) {
        CaffeineCache caffeineCache = (CaffeineCache) cacheManager.getCache(cacheName);
        if (caffeineCache != null) {
            Cache<Object, Object> nativeCache = caffeineCache.getNativeCache();
            return nativeCache.stats();
        }
        return null;
    }

    /**
     * 清除指定缓存
     */
    public void clearCache(String cacheName) {
        CaffeineCache caffeineCache = (CaffeineCache) cacheManager.getCache(cacheName);
        if (caffeineCache != null) {
            caffeineCache.clear();
            log.info("已清除缓存: {}", cacheName);
        }
    }

    /**
     * 清除所有缓存
     */
    public void clearAllCaches() {
        CACHE_NAMES.forEach(this::clearCache);
        log.info("已清除所有缓存");
    }

    /**
     * 更新缓存监控指标
     */
    private void updateCacheMetrics(String cacheName) {
        CacheStats stats = getCacheStats(cacheName);
        if (stats != null) {
            List<Tag> tags = Arrays.asList(Tag.of("cache", cacheName));

            // 记录命中率
            meterRegistry.gauge("cache.hit.ratio", tags, stats.hitRate());
            
            // 记录加载新值的平均时间
            meterRegistry.gauge("cache.load.duration", tags, 
                    stats.averageLoadPenalty() / TimeUnit.MILLISECONDS.toNanos(1));
            
            // 记录缓存大小
            CaffeineCache caffeineCache = (CaffeineCache) cacheManager.getCache(cacheName);
            if (caffeineCache != null) {
                meterRegistry.gauge("cache.size", tags, 
                        caffeineCache.getNativeCache().estimatedSize());
            }

            // 记录请求总数
            meterRegistry.gauge("cache.requests", tags, stats.requestCount());

            // 记录命中次数
            meterRegistry.gauge("cache.hits", tags, stats.hitCount());

            // 记录未命中次数
            meterRegistry.gauge("cache.misses", tags, stats.missCount());

            // 记录被驱逐的条目数
//            meterRegistry.gauge("cache.evictions", tags, stats.evictionCount());
        }
    }
} 